/*************************************************************************
	> File Name: ../common/reactor.c
	> Author: Maureen 
	> Mail: 1437867946@qq.com 
	> Created Time: Tue 12 Jan 2021 09:11:59 PM CST
 ************************************************************************/
#include "head.h"

extern int subfd;
extern struct User *users;

void add_event_ptr(int epollfd, int fd, int events, struct User *user) {
    struct epoll_event ev;
    ev.events = events;
    ev.data.ptr = (void *)user;
    epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev);
}

int add_to_reactor(int fd, struct User *user) {
    int sub = user->fd;
    users[sub] = *user; //使用文件描述符作为数组下标
    
    add_event_ptr(fd, users[sub].fd, EPOLLIN | EPOLLET, &users[sub]);
}

//从反应堆中删除用户
void delete_from_reactor(int fd) {
    epoll_ctl(subfd, EPOLL_CTL_DEL, fd, NULL);
}


//从反应堆处理消息,和主反应堆的处理是相似的
void *handle_sub_reactor(void *arg) {
    struct epoll_event events[20];
    struct Msg msg;
    while (1) {
        int nfds = epoll_wait(subfd, events, 20, -1);

        if (nfds < 0) exit(1);//线程中调用exit，会使得整个程序退出

        for (int i = 0; i < nfds; i++) {
            int fd = ((struct User *)(events[i].data.ptr))->fd;
            recv(fd, &msg, sizeof(msg), 0);
            users[fd].cnt = 5;
            if (msg.type & CHAT_HEART) { //接收到心跳
                DBG(BLUE"<%s>"NONE"  ❤ ->"BLUE"<Me>"NONE" \n", users[fd].name);
                msg.type = CHAT_ACK;
                send(fd, &msg, sizeof(msg), 0);
            } else if (msg.type & CHAT_ACK) { //回复心跳消息
                DBG(BLUE"<Me>"NONE" 👩‍❤️‍👩  ->  <%s> ❤️ \n", users[fd].name);
            } else if (msg.type & CHAT_FIN) {
                DBG("🔴  "BLUE"<%s>  👋  \n", users[fd].name);
                //epoll_ctl delete from sub_reactor
                delete_from_reactor(fd);
                close(fd);
                users[fd].flag = 0;
                DBG("🔴  "BLUE"<%s>"NONE" is leaving!\n", users[fd].name);
                DBG("🔱  "RED"<%s> is removed from sub reactor..."NONE"\n", users[fd].name);
            } else if (msg.type & CHAT_MSG) {
                DBG("🟢   "BLUE"<%s>"NONE" :  %s\n", msg.from, msg.msg);
            } else {
                DBG("🌺\n");
            }
        }
    
    }
}
